#!/usr/bin/python

#-------------------------------------------------------------------------------------------------
# Name:        game
# Purpose:     game higher test bench
#
# Author:      cackles
#
# Created:     08/31/2011
#-------------------------------------------------------------------------------------------------


import getopt
import sys, pygame
from pygame import sprite
import map as Map
import piece as Piece
from localtypes import Position, Velocity, Logger 
import pickle
import random
import os

class Game(Logger, sprite.RenderUpdates):
    def __init__(self, filename=None, rows=0, columns=0):
        self.filename = filename
        self.Map = Map.map(rows, columns)
        self.ThePlayer = sprite.GroupSingle()
        
        # pygame initialization - not sure if this'll work on loading            
        pygame.init()
        pygame.mixer.init()
        icon = pygame.image.load("images" + os.sep + "icon.gif")
        pygame.display.set_icon(icon)
        pygame.display.set_caption("Cackles Game")
        
        sprite.RenderUpdates.__init__(self)
                    
    @classmethod
    def InitFromFile(cls, filename):
        #obj = cls()
        #obj.filename = filename
        #obj.Load()
        f = open(filename, 'r')
        obj = pickle.load(f)
        f.close()
        return obj             
            
    def Save(self):
        f = open(self.filename, 'w')
        pickle.dump(self, f)
        f.close()

    #def Load(self):
    #    f = open(self.filename, 'r')
    #    self = pickle.load(f)
    #    f.close()

    def Print(self):
        print "-- Game %s --" % (self.filename)
        self.Map.Print()
        print "-- End --"

def usage():
    print "Usage: [-h] [-p <pieces>] [-x -y] [-l]"
    print " Required:"
    print "  -p,--pieces   <pieces>             Number of pieces on the piece"
    print "  -x,--rows     <rows>"
    print "  -y,--columns  <columns>"
    print "  -l,--loadfile <filename>           Load From File" 
    print " Optional:"
    print "  -h,--help                          Print this usage information"

# main method
def main():
    pieces = 0
    rows = 0
    columns = 0
    filename = ""
    random.seed(0)
    
    try:
        # set up the arguments available to the user
        opts, args = getopt.getopt(sys.argv[1:], "p:x:y:l:h", ["pieces=", "rows=", "columns=", "loadfile=", "help"])

    except getopt.GetoptError, err:
        print str(err)
        usage()
        sys.exit(1)

    # loop through the arguments passed by the user
    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        elif o in ("-p", "--pieces"):
            pieces = int(a)
        elif o in ("-x", "--columns"):
            columns = int(a)
            print "columns=%i" % columns
        elif o in ("-y", "--rows"):
            rows = int(a)
            print "rows=%i" % rows
        elif o in ("-l", "--loadfile"):
            filename = a
        else:
            assert False, "unhandled option"
            usage()

    # determine if we need to load a previous file or use command line parameters
    g = object
    if filename != "":
        g = Game.InitFromFile(filename=filename)
        rows = g.Map.rows
        columns = g.Map.columns
    elif pieces == 0 or rows == 0 or columns == 0:
        usage()
        sys.exit()
    else:
        g = Game(rows=rows, columns=columns, filename="game.save")

    g.Print()
    g.Save()
    
    size = g.Map.columns*64, g.Map.rows*64 # width, height
    screen = pygame.display.set_mode(size, pygame.DOUBLEBUF)

    # create multiple pieces
    for i in range (4, 4+pieces):
        t = Piece.tank()
        t.setPosition(Position(i-4, i-4, 0))
        t.setVelocity(Velocity((i+1)*10, (i+1)*10, 0))
        t.setMaxVelocity(Velocity((i+1)*10, (i+1)*10, 0))
        t.name = "tank %i" % i
        t.info(t.name + " created")
        g.add(t)

    # player Tank
    t = Piece.player()
    t.setPosition(Position(pieces*2, pieces*2, 0))
    t.setVelocity(Velocity(0, 0, 0))
    t.setMaxVelocity(Velocity(200, 200, 0))
    t.name = "Player" 
    t.info(t.name + " created")
    g.ThePlayer.add(t) # create the player specific reference
    g.add(t)
    
    cackles_render_map(g, screen)
    #cackles_collision_demo()


def cackles_render_map(game, screen):
    # pygame initialization

    for location in game.Map.FlatMap():
            location.image = pygame.image.load(location.imagefile).convert_alpha()
            location.mask = pygame.mask.from_surface(location.image)
            location.rect  = location.image.get_rect()
            location.rect.move_ip(location.x*64, location.y*64)    


    # create background surface
    background = pygame.Surface( (screen.get_width(), screen.get_height()) )
    for location in game.Map.FlatMap():
        background.blit(location.image, location.rect)
        
    # draw the background
    screen.blit(background, (0, 0)) 

    # get a game timer
    clock = pygame.time.Clock()
    previousLoopTime = 0 # milliseconds

    while 1:
        pygame.event.pump()
        for event in pygame.event.get():
            if event.type == pygame.QUIT: sys.exit()
         
        key=pygame.key.get_pressed()  #checking pressed keys

        up    = True if key[pygame.K_UP] else False
        down  = True if key[pygame.K_DOWN] else False
        right = True if key[pygame.K_RIGHT] else False
        left  = True if key[pygame.K_LEFT] else False
        
        for hero in game.ThePlayer.sprites():
            if up:
                hero.velocity.y -= 10
            if down:
                hero.velocity.y += 10       
            if right:
                hero.velocity.x += 10
            if left:
                hero.velocity.x -= 10
                        
        game.clear(screen, background)
        game.update(previousLoopTime, background.get_width(), background.get_height()) # currently, takes the width and height of the bounding game map
        for i in game.sprites():
            collided =  sprite.spritecollide(i, game, 0)
            for other in collided:
                if other != i:
                    i.info( i.name + " collided with " + other.name )
                    i.kill()
                    other.kill()
            
        game.draw(screen)

        #pygame.time.delay(15)
        pygame.display.flip()
        previousLoopTime = clock.tick(30) / 1000.0

    sys.exit()




def cackles_collision_demo():
    # pygame initialization
    pygame.init()
    pygame.mixer.init()
    icon = pygame.image.load("images" + os.sep + "icon.gif")
    pygame.display.set_icon(icon)
    pygame.display.set_caption("Cackles Game")
    size = width, height = 640, 480
    speed1 = [1, 2]
    speed2 = [2, 1]
    black = 0, 0, 0
    sound = pygame.mixer.Sound("sounds" + os.sep + "boom.wav")
    sound.set_volume(sound.get_volume()*0.5)

    
    screen = pygame.display.set_mode(size, pygame.DOUBLEBUF)
    
    mountain = pygame.image.load("images" + os.sep + "mountain.png").convert_alpha()
    mountainrect = mountain.get_rect()
    
    rock = pygame.image.load("images" + os.sep + "rock.png").convert_alpha()
    rockrect = rock.get_rect()
    rockrect.top = 200
    
    while 1:
        for event in pygame.event.get():
            if event.type == pygame.QUIT: sys.exit()
    
        collision = pygame.Rect.colliderect(mountainrect, rockrect)

        if collision:
            sound.stop()
            sound.play(loops=0, maxtime=0, fade_ms=0)
            speed1[0] = random.randint(1,2) if speed1[0]>0 else random.randint(-2,-1)
            speed1[1] = random.randint(1,2) if speed1[1]>0 else random.randint(-2,-1)
            speed2[0] = random.randint(1,2) if speed2[0]>0 else random.randint(-2,-1)
            speed2[1] = random.randint(1,2) if speed2[1]>0 else random.randint(-2,-1)
            
        if mountainrect.left < 0 or mountainrect.right > width or collision:
            speed1[0] = -speed1[0]
        if mountainrect.top < 0 or mountainrect.bottom > height or collision:
            speed1[1] = -speed1[1]
        if rockrect.left < 0 or rockrect.right > width or collision:
            speed2[0] = -speed2[0]
        if rockrect.top < 0 or rockrect.bottom > height or collision:
            speed2[1] = -speed2[1]
        
        
        mountainrect = mountainrect.move(speed1)
        rockrect = rockrect.move(speed2)

        screen.fill(black)
        screen.blit(mountain, mountainrect)
        screen.blit(rock, rockrect)
        pygame.display.flip()

    sys.exit()

if __name__ == '__main__':
    main()

